﻿using System;
using System.Threading;
using System.Collections.Generic;
using NUnit.Framework;

namespace com.ptrampert.LibVLCBind.Tests
{
    [TestFixture]
    public class TestMediaPlayer
    {
        private IVLCInstance vlc;
        private IMedia media;
        private IVideoPlayer player;
        private const string filename = "Robot Chicken - Atta Toy.avi";

        [TestFixtureSetUp]
        public void Initialize()
        {
            IVLCFactory factory = new TwoflowerVLCFactory();
            vlc = factory.InitializeVLC();
            media = vlc.GetVLCMedia(filename, true);
        }

        [SetUp]
        public void Init()
        {
            player = vlc.CreateMediaPlayer<IVideoPlayer>();
            player.Mute = true;
        }

        [Test]
        public void TestDisposalWhilePlaying()
        {
            player.Media = media;
            player.Play();
            Thread.Sleep(500);
        }

        [Test]
        public void TestStateToggles()
        {
            player.Media = media;
            player.Play();
            Thread.Sleep(1000);
            Assert.AreEqual(LIBVLC_STATE.PLAYING, player.State);
            Thread.Sleep(1000);
            player.Pause();
            Thread.Sleep(1000);
            Assert.AreEqual(LIBVLC_STATE.PAUSED, player.State);
            player.Stop();
            Assert.AreEqual(LIBVLC_STATE.STOPPED, player.State);
        }

        [Test]
        public void TestMedia()
        {
            player.Media = media;
            Assert.IsNotNull(player.Media);
        }

        [Test]
        public void TestLengthPosTime()
        {
            player.Media = media;
            player.Play();
            Thread.Sleep(1000);
            player.Pause();
            long length = player.Length;
            long time = player.Time;
            float position = player.Position;
            Assert.IsTrue(length > 0);
            Assert.IsTrue(time > 0 && time < length);
            Assert.IsTrue(position > 0 && position < 1);
            player.Time = 2000;
            Assert.AreEqual(2000, player.Time);
            player.Position = 0.5F;
            Assert.AreEqual(0.5F, player.Position);
        }

        [Test]
        public void TestAudioTracks()
        {
            player.Media = media;
            player.Play();
            Thread.Sleep(1000);
            player.Pause();
            Assert.IsNotNull(player.AudioTracks);
            TestTracks(player.AudioTracks);
        }

        [Test]
        public void TestAspectRatio()
        {
            player.Media = media;
            player.Play();
            Thread.Sleep(1000);
            player.Pause();
            player.AspectRatio = "16:9";
            Assert.AreEqual("16:9", player.AspectRatio);
        }

        private void TestTracks(IEnumerable<TrackDescription> tracks)
        {
            int prevID = -2;
            foreach (TrackDescription track in tracks)
            {
                Assert.AreNotEqual(prevID, track.ID);
                Assert.IsNotNull(track.Name);
                if (track.HasChildren)
                {
                    Assert.IsNotNull(track.Children);
                    TestTracks(track.Children);
                }
                prevID = track.ID;
            }
        }

        [Test]
        public void TestMediaPlayerAsync()
        {
            bool asyncCalled = false;
            player.Media = media;
            player.Playing += (object sender, EventArgs e) =>
                {
                    asyncCalled = true;
                };
            player.Play();
            Thread.Sleep(1000);
            player.Stop();
            Assert.IsTrue(asyncCalled);
        }

        [TearDown]
        public void Cleanup()
        {
            player.Dispose();
        }

        [TestFixtureTearDown]
        public void CleanupFixture()
        {
            media.Dispose();
            vlc.Dispose();
        }
    }
}
